<?php
namespace NatalPHP\View\HTML;
/* SVN FILE: $Id: Element.php 45 2010-01-10 20:05:40Z Sadjow $ */
/**
 * Element class file.
 * Defines constants of attributes to use in elements.
 * 
 * NatalPHP (tm) :  Sufficient and Simple Framework (http://www.trycatch.com.br)
 * Copyright 2010 Sadjow Medeiros Leão <sadjow[at]gmail.com>,
 * Waldson Patricio <waldsonpatricio[at]gmail.com
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @copyright     Copyright 2010 Sadjow Medeiros Leão <sadjow[at]gmail.com>,
 *                Waldson Patricio <waldsonpatricio[at]gmail.com
 * @link          http://www.trycatch.com.br Natal(tm) Project
 * @package       NatalPHP
 * @subpackage    NatalPHP.NatalPHP.View.HTML
 * @since         NatalPHP(tm) v 0.1
 * @version       $Rev: 45 $
 * @modifiedby    $LastChangedBy: Sadjow $
 * @lastmodified  $Date: 2010-01-10 20:05:40 +0000 (Sun, 10 Jan 2010) $
 * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
 */

    // Standard Attributes for all HTML elements.
    const ATTR_ACCESSKEY        = 'accesskey';
    const ATTR_CLASS            = 'class';
    const ATTR_CONTENTEDITABLE  = 'contenteditable';
    const ATTR_CONTENTMENU      = 'contextmenu';
    const ATTR_DIR              = 'dir';
    const ATTR_DRAGGABLE        = 'draggable';
    const ATTR_HIDDEN           = 'hidden';
    const ATTR_ID               = 'id';
    const ATTR_ITEM             = 'item';
    const ATTR_ITEMPROP         = 'itemprop';
    const ATTR_IRRELEVANT       = 'irrelevant';
    const ATTR_LANG             = 'lang';
    const ATTR_SPELLCHECK       = 'spellcheck';
    const ATTR_STYLE            = 'style';
    const ATTR_SUBJECT          = 'subject';
    const ATTR_REGISTRATIONMARK = 'registrationmark';
    const ATTR_TABINDEX         = 'tabindex';
    const ATTR_TEMPLATE         = 'template';
    const ATTR_TITLE            = 'title';

    // Area attributes
    const ATTR_SHAPE = 'shape';
    const ATTR_COORDS = 'coords';

    // Graphics Attributes
    const ATTR_ALT   = 'alt';

    // Hiper Reference Attributes
    const ATTR_HREF     = 'href';
    const ATTR_HREFLANG = 'hreflang';
    const ATTR_MEDIA    = 'media';
    const ATTR_PING     = 'ping';
    const ATTR_REL      = 'rel';
    const ATTR_TARGET   = 'target';

    //Forms Attributes
    const ATTR_TYPE     = 'type';
    const ATTR_VALUE    = 'value';
    const ATTR_NAME     = 'name';
    const ATTR_FORMTARGET = 'formtarget';
    const ATTR_FORMNOVALIDATE = 'formnovalidate';
    const ATTR_FORMMETHOD = 'formmethod';
    const ATTR_FORMENCTYPE = 'formenctype';
    const ATTR_FORMACTION = 'formaction';
    const ATTR_FORM = 'form';
    const ATTR_DISABLED = 'disabled';
    const ATTR_AUTOFOCUS = 'autofocus';
    
    //Article Attributes
    const ATTR_CITE = 'cite';
    const ATTR_PUBDATE = 'pubdate';

    // Audio Attributes
    const ATTR_AUTOBUFFER = 'autobuffer';
    const ATTR_AUTOPLAY = 'autoplay';
    const ATTR_CONTROLS = 'controls';
    const ATTR_SRC      = 'src';

/**
 * Class representing a HTML element.
 * With this class you can build HTML elements, add and remove attributes.
 * Insert internal content, at the beginning or end, or simply define the content.
 *
 * @package       NatalPHP
 * @subpackage    NatalPHP.NatalPHP.View.HTML
 */
abstract class Element {

    

    /*
     * The tag name of HTML element.
     *
     * @var string
     */
    private $tagName;

    /*
     * A element can be empty or not.
     *
     * @var bool
     */
    private $isEmpty = false;

    /*
     * The element content. There may be others elements.
     *
     * @var string
     */
    private $content;

    /*
     * The element attributes.
     *
     * @var array
     */
    private $attributes = array();

    /*
     * Create new element.
     *
     * @param string $tagName The element tag name.
     * @param bool $isEmpty If the element is a empty element(e.g <br />)
     */
    public function __construct($tagName, $isEmpty = false){
        $this->tagName = $tagName;
        $this->isEmpty = $isEmpty;
    }

    /*
     *  Returns a concatenated string of attributes.
     */
    private function getAttributesString(){
        $s = "";
        if(!empty ($this->attributes)){
            foreach($this->attributes as $aName => $aValue){
                $s .= " {$aName}=\"{$aValue}\"";
            }
        }
        return $s;
    }

    /*
     * Defines the content within this element.
     *
     * @param mixed $content A text or other Element.
     *
     * @return Element Return this element.
     */
    public function content($content){
        $this->content .= $content;
        return $this;
    }

    /*
     * Sets the contents of the beginning of this element.
     *
     * @param mixed $content A text or other Element.
     *
     * @return Element Return this element.
     */
    public function beforeContent($content){
        $this->content = $content . $this->content;
        return $this;
    }

    /*
     * Sets the content of the end of this element.
     *
     * @param mixed $content A text or other Element.
     *
     * @return Element Return this element.
     */
    public function afterContent($content){
        $this->content = $this->content . $content;
        return $this;
    }

    /*
     * Sets a attribute to this element.
     * If the '$value' is not set or null, returns the attribute value, if it exists.
     *
     * @param string $name The attribute name.
     * @param string $value The value of attribute.
     * 
     * @return Element Return this element.
     */
    public function attr($name, $value = null){
        if($value != null){
            $this->attributes[$name] = $value;
            return $this;
        } else {
            return (isset($this->attributes[$name])) ? $this->attributes[$name] : null;
        }
    }

    /*
     * Remove a attribute to this element.
     *
     * @param string $name The attribute name.
     * @param string $value The value of attribute.
     *
     * @return Element Return this element.
     */
    public function rattr($name){
        unset ($this->attributes[$name] );
        return $this;
    }

    /**
     * Sets if the element is a empty element.
     * Or get information about it if not giving any parameter.
     * 
     * @param bool $bool true or false
     * @return mixed Element or bool
     */
    public function isEmpty($bool = null){
        if($bool === null){
            return $this->isEmpty;
        } else {
            $this->isEmpty = $bool;
            return $this;
        }
    }

    /**
     * Sets the title. Or get if $tile is null.
     * @param string $title The title text.
     */
    public function title($title = null){
        return $this->attr(ATTR_TITLE, $title);
    }

    /*
     * Render the HTML element.
     *
     * @return string Returns the object represented in string.
     */
    public function  __toString() {
        if($this->isEmpty){
            return "<{$this->tagName}{$this->getAttributesString()} />";
        } else {
            return "<{$this->tagName}{$this->getAttributesString()}>$this->content</{$this->tagName}>";
        }
    }

}
